package org.nemanjaristic.utils;

import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class TimeUtils {

	public static String nsToString(long ns) {
		if (ns < 1000L) {
			return Long.toString(ns) + " ns";
		}
		else if (ns < 1000000L) {
			return Long.toString(ns / 1000L) + " us";
		}
		else if (ns < 1000000000L) {
			return Long.toString(ns / 1000000L) + " ms";
		}
		else if (ns < 60000000000L) {
			return String.format("%.2f s", nsToS(ns));
		}
		else {
			long duration = ns;
			//long nanoseconds = duration % 1000;
			duration /= 1000;
			//long microseconds = duration % 1000;
			duration /= 1000;
			//long milliseconds = duration % 1000;
			duration /= 1000;
			long seconds = duration % 60;
			duration /= 60;
			long minutes = duration % 60;
			duration /= 60;
			long hours = duration % 24;
			duration /= 24;
			long days = duration;

			StringBuilder result = new StringBuilder();
			if (days != 0) {
				result.append(days);
				result.append('d');
			}
			if (result.length() > 1 || hours != 0) {
				result.append(hours);
				result.append('h');
			}
			if (result.length() > 1 || minutes != 0) {
				result.append(minutes);
				result.append('m');
			}
			result.append(seconds);
			result.append('s');
			return result.toString();
		}
	}

	public static double nsToS(long ns) {
		return ((double) ns) / 1000000000.0;
	}
	
	public static String secondsToString(long s) {
		if (s < 60L) {
			return Long.toString(s) + "s";
		}
		else {
			long duration = s;
			long seconds = duration % 60;
			duration /= 60;
			long minutes = duration % 60;
			duration /= 60;
			long hours = duration % 24;
			duration /= 24;
			long days = duration;

			StringBuilder result = new StringBuilder();
			if (days != 0) {
				result.append(days);
				result.append("d ");
			}
			if (result.length() > 1 || hours != 0) {
				result.append(hours);
				result.append("h ");
			}
			if (result.length() > 1 || minutes != 0) {
				result.append(minutes);
				result.append("m ");
			}
			result.append(seconds);
			result.append('s');
			
			return result.toString();
		}
	}
	
	public static long getDaysBetween(Date startDate, Date endDate) {
		return getTimeBetween(startDate, endDate, TimeUnit.DAYS);
	}
	
	public static long getHoursBetween(Date startDate, Date endDate) {
		return getTimeBetween(startDate, endDate, TimeUnit.HOURS);
	}

	public static long getMillisecondsBetween(Date startTime, Date endTime) {
		return getTimeBetween(startTime, endTime, TimeUnit.MILLISECONDS);
	}

	private static long getTimeBetween(Date startDate, Date endDate, TimeUnit timeUnit) {
		Calendar calendarStart = Calendar.getInstance();
		calendarStart.setTime(startDate);

		Calendar calendarEnd = Calendar.getInstance();
		calendarEnd.setTime(endDate);

		return timeUnit.convert(calendarEnd.getTimeInMillis() - calendarStart.getTimeInMillis(), TimeUnit.MILLISECONDS);
	}
	
	public static boolean isSameDay(Date originalDate, Date newDate) {
		Calendar calendarOriginal = Calendar.getInstance();
		calendarOriginal.setTime(originalDate);

		Calendar calendarNew = Calendar.getInstance();
		calendarNew.setTime(newDate);

		return (calendarNew.get(Calendar.YEAR) == calendarOriginal.get(Calendar.YEAR) && calendarNew.get(Calendar.DAY_OF_YEAR) == calendarOriginal.get(Calendar.DAY_OF_YEAR));
	}
}
